package random;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public final class ASawGridShort implements ASawGrid {

	private final int size;

	private final ArrayMap mapH;

	private final ArrayMap mapV;

	private final int cellSize;

	public ASawGridShort(int cellSize, int size) {
		super();
		this.cellSize = cellSize;
		this.size = size;
		this.mapH = new ArrayMap();
		this.mapV = new ArrayMap();
	}

	/* (non-Javadoc)
	 * @see random.ASawGrid#intersectV(int, int, int)
	 */
	public final boolean intersectV(final int x, final int y, final int length) {
		final int min = length > 0 ? x + 1 : x + length;
		final int max = length > 0 ? x + length : x - 1;
		{
			final int[] coord = { min / this.cellSize, y / this.cellSize };
			final List<int[]> list = mapV.get(coord);
			if (list != null) {
				final ListIterator<int[]> it = list.listIterator(list.size());
				while (it.hasPrevious()) {
					int[] i = it.previous();
					if (min <= i[0] && i[0] <= max && i[1] <= y && y <= i[2]) {
						return true;
					}
				}
			}
		}
		if (min / this.cellSize != max / this.cellSize) {
			final int[] coord = { max / this.cellSize, y / this.cellSize };
			final List<int[]> list = mapV.get(coord);
			if (list != null) {
				final ListIterator<int[]> it = list.listIterator(list.size());
				while (it.hasPrevious()) {
					int[] i = it.previous();
					if (min <= i[0] && i[0] <= max && i[1] <= y && y <= i[2]) {
						return true;
					}
				}
			}
		}
		return false;

	}

	/* (non-Javadoc)
	 * @see random.ASawGrid#intersectH(int, int, int)
	 */
	public final boolean intersectH(final int x, final int y, final int length) {
		final int min = length > 0 ? y + 1 : y + length;
		final int max = length > 0 ? y + length : y - 1;
		{
			final int[] coord = { x / this.cellSize, min / this.cellSize };
			final List<int[]> list = mapH.get(coord);
			if (list != null) {
				final ListIterator<int[]> it = list.listIterator(list.size());
				while (it.hasPrevious()) {
					int[] i = it.previous();
					if (min <= i[0] && i[0] <= max && i[1] <= x && x <= i[2]) {
						return true;
					}
				}
			}
		}
		if (min / this.cellSize != max / this.cellSize) {
			final int[] coord = { x / this.cellSize, max / this.cellSize };
			final List<int[]> list = mapH.get(coord);
			if (list != null) {
				final ListIterator<int[]> it = list.listIterator(list.size());
				while (it.hasPrevious()) {
					int[] i = it.previous();
					if (min <= i[0] && i[0] <= max && i[1] <= x && x <= i[2]) {
						return true;
					}
				}
			}
		}
		return false;

	}

	/* (non-Javadoc)
	 * @see random.ASawGrid#addH(int, int, int)
	 */
	public final void addH(final int x, final int y, final int length) {
		final int min = length > 0 ? x : x + length;
		final int max = length > 0 ? x + length : x;
		{
			final int[] coord = { min / this.cellSize, y / this.cellSize };
			List<int[]> list = mapH.get(coord);
			if (list == null) {
				list = new LinkedList<int[]>();
				mapH.put(coord, list);
			}
			{
				final int[] i = { y, min, max };
				list.add(i);
			}
		}
		if (min / this.cellSize != max / this.cellSize) {
			final int[] coord = { max / this.cellSize, y / this.cellSize };
			List<int[]> list = mapH.get(coord);
			if (list == null) {
				list = new LinkedList<int[]>();
				mapH.put(coord, list);
			}
			{
				final int[] i = { y, min, max };
				list.add(i);
			}
		}
	}

	/* (non-Javadoc)
	 * @see random.ASawGrid#addV(int, int, int)
	 */
	public final void addV(final int x, final int y, final int length) {
		final int min = length > 0 ? y : y + length;
		final int max = length > 0 ? y + length : y;
		{
			final int[] coord = { x / this.cellSize, min / this.cellSize };
			List<int[]> list = mapV.get(coord);
			if (list == null) {
				list = new LinkedList<int[]>();
				mapV.put(coord, list);
			}
			{
				final int[] i = { x, min, max };
				list.add(i);
			}
		}
		if (min / this.cellSize != max / this.cellSize) {
			final int[] coord = { x / this.cellSize, max / this.cellSize };
			List<int[]> list = mapV.get(coord);
			if (list == null) {
				list = new LinkedList<int[]>();
				mapV.put(coord, list);
			}
			{
				final int[] i = { x, min, max };
				list.add(i);
			}
		}
	}

	private final class ArrayMap {

		private final List<int[]>[][] arr = new List[size][];

		private final void put(int[] key, List<int[]> value) {
			final int x = key[0];
			final int y = key[1];
			List<int[]>[] a;
			if ((a = arr[x]) == null) {
				a = arr[x] = new List[size];
			}
			// List<int[]>[] b;
			// if((b = a[y/SUB]) == null)
			// b = a[y/SUB] = new List[SUB];
			a[y] = value;
			return;
		}

		private final List<int[]> get(int[] key) {
			final int x = key[0];
			final int y = key[1];
			final List<int[]>[] a;
			if ((a = arr[x]) == null) {
				return null;
			}
			// final List<int[]>[] b;
			// if((b = a[y/SUB]) == null)
			// return null;
			return a[y];
		}

	}

}
